package com.nuoniu.sibanyun.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.result.HttpResult;
import com.nuoniu.sibanyun.entity.SysCompany;
import com.nuoniu.sibanyun.entity.SysOffice;
import com.nuoniu.sibanyun.entity.dto.SysOfficeDto;
import com.nuoniu.sibanyun.entity.vo.OfficeTreeData;
//import com.nuoniu.sibanyun.mapper.SysEmployeeMapper;
import com.nuoniu.sibanyun.mapper.SysOfficeMapper;
import com.nuoniu.sibanyun.mapper.SysRoleDataScopeMapper;
import com.nuoniu.sibanyun.mapper.SysUserMapper;
import com.nuoniu.sibanyun.service.ISysOfficeService;
import com.nuoniu.sibanyun.userThread.DataScope;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 组织机构表 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-05-25
 */
@Service
public class SysOfficeServiceImpl extends ServiceImpl<SysOfficeMapper, SysOffice> implements ISysOfficeService {

    @Autowired
    private SysRoleDataScopeMapper sysRoleDataScopeMapper;
//    @Autowired
//    private SysEmployeeMapper employeeMapper;
    @Autowired
    private SysOfficeMapper officeMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public List<OfficeTreeData> getOfficeTreeDataList(SysOfficeDto sysOfficeDto) {
        UserInfo userInfo = UserThreadLocal.get();
        sysOfficeDto.setCompanyId(userInfo.getCompanyId());
        List<OfficeTreeData> sysOfficeList = officeMapper.getOfficeTree(sysOfficeDto);
        List<OfficeTreeData> officeData = new ArrayList<>();
        officeData.addAll(sysOfficeList);
        //加载用户
        if(sysOfficeDto.getIsLoadUser() != null && sysOfficeDto.getIsLoadUser() == 2) {
            for(OfficeTreeData office : sysOfficeList) {
                List<OfficeTreeData> employee = sysUserMapper.getByOffice(Long.parseLong(office.getId()));
                if(employee.size() > 0) {
                    officeData.addAll(employee);
                    office.setTreeLeaf(false);
                }else {
                    if(office.getParentId().equals("0")) {
                        office.setTreeLeaf(false);
                    }else {
                        office.setTreeLeaf(true);
                    }
                }
            }
        }
        return officeData;
    }

    @Override
    public List<String> checkOfficeList(Long roleId, String type) {
        if(type.equals("office")) {
            return sysRoleDataScopeMapper.checkOfficeList(roleId, type);
        }else {
            return sysRoleDataScopeMapper.checkUserList(roleId, type);
        }
    }

    @Override
    public List<SysOffice> getOfficeList(SysOfficeDto sysOfficeDto) {
        UserInfo userInfo = UserThreadLocal.get();
        SysOffice sysOffice = new SysOffice();
        QueryWrapper<SysOffice> queryWrapper = new QueryWrapper<>(sysOffice);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        if(StringUtils.isNotBlank(sysOfficeDto.getOfficeName())){
            queryWrapper.like("office_name", sysOfficeDto.getOfficeName());
        }
        if(StringUtils.isNotBlank(sysOfficeDto.getOfficeCode())) {
            queryWrapper.and(wrapper -> wrapper.like("office_name", sysOfficeDto.getOfficeCode()).or().likeRight("office_code", sysOfficeDto.getOfficeCode()));
        }
        if(sysOfficeDto.getParentId() != null) {
            queryWrapper.apply("(FIND_IN_SET(" + sysOfficeDto.getParentId() + ", parent_ids ) or id="+ sysOfficeDto.getParentId() +")");
        }
        queryWrapper.orderByAsc("office_code");
        return list(queryWrapper);
    }

    @Override
    public void deleteSysOffice(Long id, Long parentId) {
        List<OfficeTreeData> employee = sysUserMapper.getByOffice(id);
        if(employee.size() > 0) {
            throw new NuoNiuException("该机构下有员工数据，不能删除");
        }

        removeById(id);
        //判断父级是否末级
        List<SysOffice> officeList = officeMapper.getOfficeByParentId(parentId);
        if(officeList.size() == 0) {
            officeMapper.updateLevel(parentId.intValue(), 1);
        }
    }

    @Override
    public void updateLevel(Integer parentId, Integer leaf) {
        officeMapper.updateLevel(parentId, leaf);
    }

    @Override
    public void updateCompanyName(SysCompany company) {
        officeMapper.updateCompanyName(company);
        SysOffice office = officeMapper.getParentName(company.getId());
        updateOfficeName(office);
    }

    @Override
    @Async
    public void updateOfficeName(SysOffice sysOffice) {
        String[] tableNames = {"pub_customer", "sys_user"};
        for(int i=0; i<tableNames.length; i++) {
            officeMapper.updateOfficeName(tableNames[i], sysOffice.getId(), sysOffice.getOfficeName());
        }
    }

    @Override
    public List<SysOffice> getLowerLevelOffice(Long id) {

        return null;
    }

    @Override
    public void updateParentIds(Long id, String parentIds) {

    }

    @Override
    public Set<String> findAllOffices(Set<String> officeIds) {
        Set<String> allOffices = baseMapper.findAllOfficeIds(officeIds);
        return allOffices;
    }

    @Override
    public Boolean checkCode(SysOffice sysOffice, SysOffice parentOffice) {
        if(parentOffice != null && StringUtils.isNotBlank(parentOffice.getOfficeCode())) {
            String currentLevelCode = StringUtils.substringAfter(sysOffice.getOfficeCode(), parentOffice.getOfficeCode());
            if(StringUtils.isBlank(currentLevelCode)) {
                return false;
            }
            if(sysOffice.getOfficeCode().length() - 2 != parentOffice.getOfficeCode().length()) {
                return false;
            }
        }else {
            if (sysOffice.getOfficeCode().length() != 2) {
                return false;
            }
        }
        return true;
    }

    @Override
    public SysOffice getByCode(String officeCode) {
        return baseMapper.getByCode(officeCode, UserThreadLocal.get().getCompanyId());
    }

    @Override
    public Page<SysOffice> pageList(Page pages, SysOfficeDto sysOfficeDto) {
        UserInfo userInfo = UserThreadLocal.get();
        SysOffice sysOffice = new SysOffice();
        QueryWrapper<SysOffice> queryWrapper = new QueryWrapper<>(sysOffice);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        if(StringUtils.isNotBlank(sysOfficeDto.getOfficeName())){
            queryWrapper.like("office_name", sysOfficeDto.getOfficeName());
        }
        if(StringUtils.isNotBlank(sysOfficeDto.getOfficeCode())) {
            queryWrapper.and(wrapper -> wrapper.like("office_name", sysOfficeDto.getOfficeCode()).or().likeRight("office_code", sysOfficeDto.getOfficeCode()));
        }
        if(sysOfficeDto.getParentId() != null) {
            queryWrapper.apply("(FIND_IN_SET(" + sysOfficeDto.getParentId() + ", parent_ids ) or id="+ sysOfficeDto.getParentId() +")");
        }
        queryWrapper.orderByAsc("id");
        return page(pages, queryWrapper);
    }

    @Override
    public List<OfficeTreeData> getDataScopeOffice() {
        List<OfficeTreeData> result = new ArrayList<>();
        UserInfo userInfo = UserThreadLocal.get();
        DataScope dataScope = userInfo.getDataScope();
        //权限类型(1.个人 2.本部门 3.本公司 4.跨部门 5.自定义人员 6:跨部门 + 自定义人员)
        Integer type = dataScope.getType();
        String officeIds = dataScope.getOfficeIds();
        List<String> ids = null;
        if(StringUtils.isNotBlank(officeIds)){
            String[] split = StringUtils.split(officeIds, ",");
            ids =  Arrays.asList(split);
        }
        switch (type){
            case 1:
            case 5:return null;
            case 2:
            case 4:
            case 6:
                result = baseMapper.findAllOffices(ids);break;
            case 3:
                result = baseMapper.findAllOfficesByCompanyId(userInfo.getCompanyId());break;

        }
        return result;
    }

    @Override
    public void saveOffice(SysOffice sysOffice) {
        UserInfo userInfo = UserThreadLocal.get();
        sysOffice.setCompanyId(userInfo.getCompanyId());
        SysOffice parentOffice = this.getById(sysOffice.getParentId());
        Boolean result = this.checkCode(sysOffice, parentOffice);
        if(!result) {
            throw new NuoNiuException("编码不符合规则");
        }

        SysOffice officeByCode = this.getByCode(sysOffice.getOfficeCode());
        if(officeByCode != null && (!officeByCode.getId().equals(sysOffice.getId()) || sysOffice.getId() == null)) {
            throw new NuoNiuException("编码已存在");
        }

        SysOffice officeByName = baseMapper.getOfficeName(sysOffice.getOfficeName(), userInfo.getCompanyId().longValue());
        if(officeByName != null && (!officeByName.getId().equals(sysOffice.getId()) || sysOffice.getId() == null)) {
            throw new NuoNiuException("名称已存在");
        }

        if(sysOffice.getId() != null) {
            if((sysOffice.getId().toString()).equals(sysOffice.getParentId().toString())) {
                throw new NuoNiuException("父级不能选择自己");
            }

            //修改下级的父级ids
            this.updateChildrenParentIds(sysOffice, parentOffice);
            sysOffice.setUpdateDate(LocalDateTime.now());
            this.updateById(sysOffice);
            //同步修改机构数据
            this.updateOfficeName(sysOffice);
        } else {
            if (parentOffice.getParentIds().endsWith(",")) {
                sysOffice.setParentIds(parentOffice.getParentIds() + parentOffice.getId() + ",");
            } else {
                sysOffice.setParentIds(parentOffice.getParentIds() + "," + parentOffice.getId() + ",");
            }

            sysOffice.setTreeNames(parentOffice.getTreeNames() + "/" + parentOffice.getOfficeName());
            this.save(sysOffice);
            this.updateLevel(sysOffice.getParentId(), 0);
        }
    }


    @Override
    public void updateChildrenParentIds(SysOffice sysOffice, SysOffice parentOffice) {
        SysOffice office = this.getById(sysOffice.getId());
        if(office.getParentId() != sysOffice.getParentId()) {
            String newTreeNames = parentOffice.getTreeNames() + "/" + parentOffice.getOfficeName();
            String newParentIds = parentOffice.getParentIds() + parentOffice.getId() + ",";
            officeMapper.updateChildrenParentIds(sysOffice.getId(), office.getParentIds(), office.getTreeNames(),newParentIds, newTreeNames);
        }
    }
}
